JavaScript Obfuscator Toolによって難読化されたコードを解読する
結論
オリジナルのコード
code:元のコード.js
window.onload = async () => {
const canvas = document.getElementById('canvas');
const encrypted = await fetch('encrypted.json').then(res => res.json());
const decrypted = await aesDecrypt(encrypted, password, salt);
const dataURL = "data:image/png;base64," + decrypted;
createImageBitmap(toBlob(dataURL)).then(bitmap => {
canvas.width = bitmap.width;
canvas.height = bitmap.height;
const ctx = canvas.getContext('2d');
ctx.drawImage(bitmap, 0, 0);
// add copyright
ctx.font = "22px MS Gothic";
ctx.fillStyle = '#ff0000';
ctx.fillText("© potproject.net", canvas.width - 200, canvas.height - 10);
});
};
code:js
function _0x4d7a(){const _0x3bb07e='data:image/png;base64,','width','11RiQsBp','180iGddEv','22px\x20MS\x20Gothic','1334792EMuHJf','canvas','fillText','drawImage','479464EJhZCq','encrypted.json','font','onload','949012jNxTNL','1754005gGOmHM','669890VKBkoH','32742948ZjJXRR','6csxFgI','getContext','#ff0000','then','height','©\x20potproject.net','18fISgEc','12mZCZfc','115220CdTPcj','fillStyle';_0x4d7a=function(){return _0x3bb07e;};return _0x4d7a();}function _0x976d(_0x4b29df,_0x3d8f0b){const _0x4d7a49=_0x4d7a();return _0x976d=function(_0x976d64,_0x2bac82){_0x976d64=_0x976d64-0x1db;let _0x3d7352=_0x4d7a49_0x976d64;return _0x3d7352;},_0x976d(_0x4b29df,_0x3d8f0b);}const _0x2c4e60=_0x976d;(function(_0x171535,_0x4522f3){const _0x4361a4=_0x976d,_0x3e3d86=_0x171535();while(!![]){try{const _0x39b329=-parseInt(_0x4361a4(0x1e5))/0x1+parseInt(_0x4361a4(0x1dd))/0x2*(-parseInt(_0x4361a4(0x1e9))/0x3)+-parseInt(_0x4361a4(0x1f0))/0x4*(-parseInt(_0x4361a4(0x1e6))/0x5)+parseInt(_0x4361a4(0x1db))/0x6*(-parseInt(_0x4361a4(0x1f1))/0x7)+-parseInt(_0x4361a4(0x1e1))/0x8+-parseInt(_0x4361a4(0x1ef))/0x9*(parseInt(_0x4361a4(0x1e7))/0xa)+parseInt(_0x4361a4(0x1f5))/0xb*(parseInt(_0x4361a4(0x1e8))/0xc);if(_0x39b329===_0x4522f3)break;else _0x3e3d86'push'(_0x3e3d86'shift'());}catch(_0x1d28fc){_0x3e3d86'push'(_0x3e3d86'shift'());}}}(_0x4d7a,0xc59fb),window_0x2c4e60(0x1e4)=async()=>{const _0x626012=_0x2c4e60,_0x3d416a=document'getElementById'(_0x626012(0x1de)),_0x348a22=await fetch(_0x626012(0x1e2))'then'(_0x5a941f=>_0x5a941f'json'()),_0x5dfdc0=await aesDecrypt(_0x348a22,password,salt),_0x155ed2=_0x626012(0x1f3)+_0x5dfdc0;createImageBitmap(toBlob(_0x155ed2))_0x626012(0x1ec)(_0xba823b=>{const _0x1d635f=_0x626012;_0x3d416a_0x1d635f(0x1f4)=_0xba823b'width',_0x3d416a'height'=_0xba823b_0x1d635f(0x1ed);const _0x4230f2=_0x3d416a_0x1d635f(0x1ea)('2d');_0x4230f2_0x1d635f(0x1e0)(_0xba823b,0x0,0x0),_0x4230f2_0x1d635f(0x1e3)=_0x1d635f(0x1dc),_0x4230f2_0x1d635f(0x1f2)=_0x1d635f(0x1eb),_0x4230f2_0x1d635f(0x1df)(_0x1d635f(0x1ee),_0x3d416a_0x1d635f(0x1f4)-0xc8,_0x3d416a_0x1d635f(0x1ed)-0xa);});}); 機械による解読
code:js
function _0x4d7a() {
const _0x3bb07e = "data:image/png;base64,", "width", "11RiQsBp", "180iGddEv", "22px MS Gothic", "1334792EMuHJf", "canvas", "fillText", "drawImage", "479464EJhZCq", "encrypted.json", "font", "onload", "949012jNxTNL", "1754005gGOmHM", "669890VKBkoH", "32742948ZjJXRR", "6csxFgI", "getContext", "#ff0000", "then", "height", "© potproject.net", "18fISgEc", "12mZCZfc", "115220CdTPcj", "fillStyle"; _0x4d7a = function () {
return _0x3bb07e;
};
return _0x4d7a();
}
function _0x976d(_0x4b29df, _0x3d8f0b) {
const _0x4d7a49 = _0x4d7a();
return _0x976d = function (_0x976d64, _0x2bac82) {
_0x976d64 = _0x976d64 - 475;
return _0x3d7352;
}, _0x976d(_0x4b29df, _0x3d8f0b);
}
const _0x2c4e60 = _0x976d;
(function (_0x171535, _0x4522f3) {
const _0x4361a4 = _0x976d, _0x3e3d86 = _0x171535();
while (true) {
try {
const _0x39b329 = -parseInt(_0x4361a4(485)) / 1 + parseInt(_0x4361a4(477)) / 2 * (-parseInt(_0x4361a4(489)) / 3) + -parseInt(_0x4361a4(496)) / 4 * (-parseInt(_0x4361a4(486)) / 5) + parseInt(_0x4361a4(475)) / 6 * (-parseInt(_0x4361a4(497)) / 7) + -parseInt(_0x4361a4(481)) / 8 + -parseInt(_0x4361a4(495)) / 9 * (parseInt(_0x4361a4(487)) / 10) + parseInt(_0x4361a4(501)) / 11 * (parseInt(_0x4361a4(488)) / 12);
if (_0x39b329 === _0x4522f3) break; else _0x3e3d86.push(_0x3e3d86.shift());
} catch (_0x1d28fc) {
_0x3e3d86.push(_0x3e3d86.shift());
}
}
const _0x626012 = _0x2c4e60, _0x3d416a = document.getElementById(_0x626012(478)), _0x348a22 = await fetch(_0x626012(482)).then(_0x5a941f => _0x5a941f.json()), _0x5dfdc0 = await aesDecrypt(_0x348a22, password, salt), _0x155ed2 = _0x626012(499) + _0x5dfdc0;
const _0x1d635f = _0x626012;
});
});
code:js
window.onload = async () => {
const canvas = document.getElementById('canvas')
const encrypted = await fetch('encrypted.json').then((res) => res.json())
const decrypted = await aesDecrypt(encrypted, password, salt)
const dataURL = 'data:image/png;base64,' + decrypted
createImageBitmap(toBlob(dataURL)).then((bitmap) => {
canvas.width = bitmap.width
canvas.height = bitmap.height
const ctx = canvas.getContext('2d')
ctx.drawImage(bitmap, 0, 0)
ctx.font = '22px MS Gothic'
ctx.fillStyle = '#ff0000'
ctx.fillText('\xA9 potproject.net', canvas.width - 200, canvas.height - 10)
})
}
GPT-4.icon
この難読化されたJavaScriptのコードは、ウェブページ上に画像を表示し、その画像の下に "© potproject.net" という文字を描画する処理を行います。ただし、その画像は特定のURLから取得し、AESによる復号化が必要なようです。
元のJavaScriptコードは、以下のようになるでしょう:
code:gpt-4.js
window.onload = async () => {
const canvas = document.getElementById('canvas');
const encryptedData = await fetch('encrypted.json').then(response => response.json());
const decryptedData = await aesDecrypt(encryptedData, password, salt);
const imageData = 'data:image/png;base64,' + decryptedData;
createImageBitmap(toBlob(imageData)).onload = (image) => {
canvas.width = image.width;
canvas.height = image.height;
const context = canvas.getContext('2d');
context.drawImage(image, 0, 0);
context.font = '22px MS Gothic';
context.fillStyle = '#ff0000';
context.fillText('© potproject.net', canvas.width - 200, canvas.height - 10);
};
};
このコードでは aesDecrypt と toBlob という関数が使われていますが、これらの関数は定義されていません。これらの関数は、おそらく同じスクリプトまたは別のスクリプトで定義されていると思われます。
また、passwordとsaltも定義されていませんが、これらはおそらく暗号化の解除に使用する秘密キーや塩(ランダムなデータ)です。
注意: このコードは難読化されているため、正確な逆コンパイルは難しいです。したがって、提供したコードは元のコードの一例であり、実際の元のコードは異なる場合があります。ただし、元のコードが行う主な動作は上述のとおりです。
差分を見てみると、変数名が違うだけで完璧に解読されている
変数名は不可逆的に変換されているので、異なるのは当然
https://gyazo.com/ac41d27e1e2fabf9eb467a8a66fed6df